home *** CD-ROM | disk | FTP | other *** search
- From: rich@oxtrap.UUCP (K. Richard Magill)
- Newsgroups: comp.sources.misc
- Subject: v02i043: mcat - a cat utility for mmap only devices
- Message-ID: <7179@ncoast.UUCP>
- Date: 3 Feb 88 02:32:06 GMT
- Approved: allbery@ncoast.UUCP
-
- Comp.sources.misc: Volume 2, Issue 43
- Submitted-By: "K. Richard Magill" <rich@oxtrap.UUCP>
- Archive-Name: mcat
-
- [For Sequents in particular and 4.xBSD with mmap() in general. ++bsa]
-
- Note: This program uses getopt(3) which doesn't ordinarily exist in
- the berkeley universe. The at&t code for getopt is around and has
- been released into the public domain. (At least, that's my
- understanding).
-
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting test in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # mcat.l
- # mcat.c
- # This archive created: Fri Nov 27 18:19:07 EST 1987 by rich@oxtrap
- echo extracting mcat.l
- sed 's/^X//' >mcat.l << 'END-of-mcat.l'
- X.TH MCAT l "27 Nov 87" "local"
- X.SH NAME
- Xmcat \- cat like program for read/write'ing pmap devices from shell
- X.SH SYNOPSIS
- X.B mcat
- X[-b buffersize] [-i ifile] [-o ofile] [-s] [-v]
- X.SH DESCRIPTION
- X.I mcat
- Xis a program very much like cat or dd that is capable of reading a
- Xnon-read(2)'able device, for example, an mmap(2) only device like
- Xsequent's pmap devices. It is capable of copying mmap to mmap,
- Xreading and writing onto mmap or reading from mmap and writing.
- X.SH OPTIONS
- X.PP
- X.TP 14
- X.B \-b buffersize
- Xuse buffersize as the buffer size for read's and write's rather than BUFSIZ.
- X.PP
- X.TP 14
- X.B \-i ifile
- Xuse ifile as file name for input rather than stdin.
- X.PP
- X.TP 14
- X.B \-o ofile
- Xuse ofile as file name for output rather than stdout.
- X.PP
- X.TP 14
- X.B \-s
- Xprint no error messages. (silent).
- X.PP
- X.TP 14
- X.B \-v
- Xprint some log lines. (verbose).
- X.SH BUGS
- XDue to a synergy of shell strategy, and balance hardware limitations,
- Xyou can not redirect stdout to a pmap device on sequent balance. (but
- Xyou can use -o ofile).
- X.SH AUTHOR
- XK. Richard Magill - Digital Works Ltd.
- X
- Xrich@oxtrap.UUCP, rich@sendai.UUCP
- END-of-mcat.l
- echo extracting mcat.c
- sed 's/^X//' >mcat.c << 'END-of-mcat.c'
- X/*
- X * This file is mcat.c and contains a sort of cat utility for use with
- X * pmap devices. It was originally written on sequent Dynix 2.1.1.
- X *
- X * to do:
- X * mmap disk files.
- X * mcat multiple files in, out.
- X * -x write at offset x.
- X * trunc old disk files.
- X *
- X * Original Author: K. Richard Magill Fri Nov 20 16:00:53 EST 1987
- X * Last Mod Fri Nov 27 18:06:15 EST 1987, by rich@oxtrap
- X *
- X *$Header: /u1/rich/bin/src/RCS/mcat.c,v 1.1 87/11/27 18:06:45 rich Exp $
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/ioctl.h>
- X#include <sys/mman.h>
- X#include <sys/stat.h>
- X#include <machine/pmap.h>
- X
- X#define Perror(s) {if(Silent==0)perror(s);}
- X
- Xchar *valloc();
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char *InBase = ((char *) 0);
- X char *OutBase = ((char *) 0);
- X
- X int BufferSize = BUFSIZ;
- X int InPut = fileno(stdin);
- X int OutPut = fileno(stdout);
- X int Silent = 0;
- X int Verbose = 0;
- X int WriteFlags = 0;
- X int c;
- X
- X struct pmap_ioc InSize, OutSize;
- X struct stat Readable;
- X
- X extern char *optarg;
- X extern int optind;
- X
- X/*
- X * parse args.
- X */
- X
- X while ((c = getopt(argc, argv, "b:i:o:sv")) != EOF) {
- X switch (c) {
- X
- X case 'b':
- X BufferSize = atoi(optind);
- X
- X if (Verbose != 0) {
- X (void) fprintf(stderr,
- X "%s: Using %d byte i/o.\n",
- X argv[0], BufferSize);
- X } /* verbose */
- X
- X break;
- X
- X case 'i':
- X
- X if ((InPut = open(optarg, O_RDONLY, 0666)) < 0) {
- X Perror("opening input:");
- X exit(1);
- X } /* on error opening for read */
- X
- X break;
- X
- X case 'o':
- X if (access(optarg, F_OK) == 0) {
- X if (Verbose != 0) {
- X (void) fprintf(stderr, "%s: output exists.\n", argv[0]);
- X } /* verbose */
- X
- X if (access(optarg, R_OK) == 0) {
- X if (Verbose != 0) {
- X (void) fprintf(stderr, "%s: output is readable.\n", argv[0]);
- X } /* verbose */
- X
- X WriteFlags |= O_RDWR;
- X }
- X
- X } else {
- X if (Verbose != 0) {
- X (void) fprintf(stderr, "%s: output does not exist. creating.\n", argv[0]);
- X } /* verbose */
- X
- X WriteFlags = O_CREAT | O_RDWR;
- X }
- X
- X if ((OutPut = open(optarg, WriteFlags, 0666)) < 0) {
- X Perror("mcat: opening output");
- X exit(1);
- X } /* on error opening for write */
- X
- X break;
- X
- X case 's':
- X Silent = 1;
- X break;
- X
- X case 'v':
- X Verbose = 1;
- X break;
- X
- X case '?':
- X default:
- X if (Silent == 0) {
- X (void) fprintf(stderr, "%s: usage: -b buffer_size -i input_file -o output_file -s -v\n", argv[0]);
- X } /* not silent */
- X
- X exit(1);
- X
- X } /* switch on switch character */
- X } /* while there are switch characters */
- X
- X/*
- X * I presume that if the ioctl fails, this is not a pmap device and we
- X * aren't mapping. If you know of a better way to check a a descriptor
- X * for mmap'ability, (short of chasing the major number through the kernel),
- X * let me know.
- X */
- X
- X if (ioctl(InPut, PMAPIOCGETP, &InSize) == 0) { /* not pmap */
- X if ((InBase = valloc(InSize.pi_size)) == 0) {
- X Perror("valloc'ing output buffer:");
- X exit(1);
- X } /* on error valloc'ing */
- X
- X if (mmap(InBase, InSize.pi_size, PROT_READ, MAP_SHARED,
- X InPut, 0) != 0) {
- X Perror("on error mmap'ing input:");
- X exit(1);
- X } /* on error mmap'ing input */
- X
- X if (Verbose != 0) {
- X (void) fprintf(stderr, "%s: mmap'ing input.\n",
- X argv[0]);
- X } /* verbose */
- X
- X } /* not mapped or not mappable */
- X
- X if ((ioctl(OutPut, PMAPIOCGETP, &OutSize) == 0)) { /* not mapping */
- X if ((OutBase = valloc(OutSize.pi_size)) == 0) {
- X Perror("valloc'ing for output buffer:");
- X exit(1);
- X } /* on valloc error */
- X
- X if (mmap(OutBase, OutSize.pi_size, PROT_RDWR, MAP_SHARED,
- X OutPut, 0) != 0) {
- X Perror("mmap'ing output:");
- X
- X if (Silent == 0) {
- X (void) fprintf(stderr, "%s: remember you can't redirect output.\n", argv[0]);
- X } /* not silent */
- X
- X exit(1);
- X } /* on error mmap'ing output */
- X
- X if (Verbose != 0) {
- X (void) fprintf(stderr, "%s: mmap'ing output.\n",
- X argv[0]);
- X } /* verbose */
- X
- X } /* not mapped or not mappable */
- X
- X if (InBase != ((char *) NULL)) { /* mapping input */
- X if (OutBase != ((char *) NULL)) { /* and output */
- X bcopy(InBase, OutBase,
- X (InSize.pi_size < OutSize.pi_size)
- X ? InSize.pi_size : OutSize.pi_size);
- X
- X } else { /* map in, no map out */
- X int ReallyWrote;
- X
- X while (InSize.pi_size > 0) {
- X if (BufferSize > InSize.pi_size) {
- X BufferSize = InSize.pi_size;
- X } /* if buffer now holds it all */
- X
- X if ((ReallyWrote = write(OutPut, InBase,
- X BufferSize)) == -1) {
- X Perror("writing output:");
- X exit(1);
- X } /* on error writing */
- X
- X InSize.pi_size -= ReallyWrote;
- X InBase += ReallyWrote;
- X } /* while data to write */
- X } /* if mapping output */
- X
- X } else { /* not mapping input */
- X
- X if (OutBase != ((char *) NULL)) { /* but mapping output */ int ReallyRead = 1;
- X
- X while (ReallyRead != 0 && OutSize.pi_size > 0) {
- X if (BufferSize > OutSize.pi_size) {
- X BufferSize = OutSize.pi_size;
- X } /* if buffer now holds it all */
- X
- X if ((ReallyRead = read(InPut, OutBase,
- X BufferSize)) == -1) {
- X Perror("reading input:");
- X exit(1);
- X } /* on error reading */
- X
- X OutSize.pi_size -= ReallyRead;
- X OutBase += ReallyRead;
- X } /* while data to write */
- X
- X } else { /* mapping nothing, should use cat instead */
- X if (Silent == 0) {
- X (void) fprintf(stderr, "%s: not mapping anything. use cat instead.\n", argv[0]);
- X } /* not silent */
- X
- X exit(1);
- X } /* if mapping output */
- X } /* if mapping input */
- X
- X exit(0);
- X} /* main() */
- X
- X/*
- X * $Log: mcat.c,v $
- X * Revision 1.1 87/11/27 18:06:45 rich
- X * Initial revision
- X *
- X *
- X * Local Variables:
- X * comment-column: 0
- X * fill-column: 75
- X * fill-prefix: " * "
- X * mode: c
- X * version-control: t
- X * End:
- X */
- X
- X/* end of mcat.c */
- END-of-mcat.c
- exit
-